//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <cprocess.h>
#include <cevent.h>
#include <sysevent.h>
#include <aura.h>

static DLinkNode s_eventList;// = { &s_eventList, &s_eventList };
static _ELASTOS PVoid s_listLock;

void InitSystemEventLock()
{
    s_eventList.Initialize();
    AuraCriticalSection_Create(&s_listLock);
}

CSystemEvent *CreateSystemEvent(CProcess *pOwner, Boolean bManualReset)
{
    CSystemEvent *pSysEvent;

    pSysEvent = new CSystemEvent(pOwner, bManualReset);
    if (NULL == pSysEvent) return NULL;

    AuraCriticalSection_Enter(s_listLock);
    s_eventList.InsertPrev(pSysEvent);
    AuraCriticalSection_Leave(s_listLock);

    pSysEvent->AddRef();
    return pSysEvent;
}

void DetachSystemEvent(CSystemEvent *pSystemEvent)
{
    AuraCriticalSection_Enter(s_listLock);
    pSystemEvent->Detach();
    AuraCriticalSection_Leave(s_listLock);
}

void TriggerSystemEvent(SystemEvent sysEvent)
{
    assert(0 != sysEvent);
    CSystemEvent *pSystemEvent;

    AuraCriticalSection_Enter(s_listLock);
    ForEachDLinkNode(CSystemEvent *, pSystemEvent, &s_eventList) {
        pSystemEvent->Trigger(sysEvent);
    }
    AuraCriticalSection_Leave(s_listLock);
}

void ClearSystemEvent(SystemEvent sysEvent)
{
    assert(0 != sysEvent);
    CSystemEvent *pSystemEvent;

    AuraCriticalSection_Enter(s_listLock);
    ForEachDLinkNode(CSystemEvent *, pSystemEvent, &s_eventList) {
        pSystemEvent->Clear(sysEvent);
    }
    AuraCriticalSection_Leave(s_listLock);
}

void TriggerSystemEvent(CProcess *pOwner, SystemEvent sysEvent)
{
    assert(0 != sysEvent);
    CSystemEvent *pSystemEvent;

    AuraCriticalSection_Enter(s_listLock);
    ForEachDLinkNode(CSystemEvent *, pSystemEvent, &s_eventList) {
        if (pOwner == pSystemEvent->m_pOwner) {
            pSystemEvent->Trigger(sysEvent);
            break;
        }
    }
    AuraCriticalSection_Leave(s_listLock);
}

void ClearSystemEvent(CProcess *pOwner, SystemEvent sysEvent)
{
    assert(0 != sysEvent);
    CSystemEvent *pSystemEvent;

    AuraCriticalSection_Enter(s_listLock);
    ForEachDLinkNode(CSystemEvent *, pSystemEvent, &s_eventList) {
        if (pOwner == pSystemEvent->m_pOwner) {
            pSystemEvent->Clear(sysEvent);
            break;
        }
    }
    AuraCriticalSection_Leave(s_listLock);
}
